package com.lwl.java8.chapter11;

import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

import com.lwl.java8.chapter11.Discount.Code;

/**
 * Created by liwenlong on 2017/12/21 17:33 <br/>
 */
public class Shop {

	private String shopName;

	public Shop(String shopName) {
		this.shopName = shopName;
	}

	public String getName() {
		return shopName;
	}

	/**
	 * 依据指定产品名称返回价格
	 * @param product
	 * @return
	 */
	public String getPrice(String product) {
		double price = calculatePrice(product);
		Code code = Discount.Code.values()[random.nextInt(Discount.Code.values().length)];
		return String.format("%s:%.2f:%s", shopName, price, code);
	}

	public Future<Double> getPriceAsync(String product) {
		CompletableFuture<Double> futurePrice = new CompletableFuture<>();
		// 线程异步执行
		new Thread(() -> {
			try {
				double price = calculatePrice(product);
				// 如果价格计算正常结束，完成 Future 操作并设置商品价格
				futurePrice.complete(price);
			} catch (Exception e) {
				// 否则就抛出导致失败的异常，完成这次 Future 操作
				futurePrice.completeExceptionally(e);
			}
		}).start();
		return futurePrice;
	}

	/**
	 * 使用工厂方法创建Future
	 * 
	 * @param product
	 * @return
	 */
	public Future<Double> getPriceAsync2(String product) {
		return CompletableFuture.supplyAsync(() -> calculatePrice(product));
	}

	/**
	 * 模拟1秒钟延迟的方法
	 */
	private static void delay() {
		try {
			Thread.sleep(1000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private Random random = new Random();

	private double calculatePrice(String product) {
		delay();
		return random.nextDouble() * product.charAt(0) + product.charAt(1);
	}

}
